package com.ozo.boot.common.file.strategy;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.aliyun.oss.model.DeleteObjectsResult;
import com.ozo.boot.common.file.constant.FileStoreTypeEnum;
import com.ozo.boot.common.file.config.FileStoreProperties;
import com.ozo.boot.common.file.config.StrategyFactory;
import io.minio.messages.DeleteObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 阿里云策略实现
 *
 * @author qiangesoft
 * @date 2024-05-13
 */
@Slf4j
@RequiredArgsConstructor
public class AliyunStrategyImpl implements FileStrategy {

    private OSS ossClient;

    public AliyunStrategyImpl(FileStoreProperties fileStoreProperties) {
        this.ossClient = new OSSClientBuilder()
                .build(fileStoreProperties.getEndpoint(),
                        fileStoreProperties.getAccessKey(),
                        fileStoreProperties.getSecretKey());
    }

    @Override
    public boolean existsCatalog(String catalog) throws Exception {
        return ossClient.doesBucketExist(catalog);
    }

    @Override
    public void createCatalog(String catalog) throws Exception {
        if (!this.existsCatalog(catalog)) {
            ossClient.createBucket(catalog);
        }
    }

    @Override
    public List<String> listCatalogs() throws Exception {
        return ossClient.listBuckets().stream().map(Bucket::getName).collect(Collectors.toList());
    }

    @Override
    public void removeCatalog(String catalog) throws Exception {
        ossClient.deleteBucket(catalog);
    }

    @Override
    public String uploadFile(String catalog, MultipartFile file) throws Exception {
        // 参数校验
        Assert.notNull(catalog, "bucketName is not blank");
        Assert.notNull(file, "file is not null");

        // 判断存储桶是否存在
        createCatalog(catalog);

        // 文件名
        String filename = file.getOriginalFilename();

        // 上传
        ossClient.putObject(catalog, filename, file.getInputStream());
        return catalog + SLASH + filename;
    }

    @Override
    public void removeFile(String catalog, String fileName) throws Exception {
        ossClient.deleteObject(catalog, fileName);
    }

    @Override
    public void removeFiles(String catalog, List<String> fileNames) throws Exception {
        List<DeleteObject> deleteObjectList = new ArrayList<>();
        for (String fileName : fileNames) {
            DeleteObject deleteObject = new DeleteObject(fileName);
            deleteObjectList.add(deleteObject);
        }

        DeleteObjectsResult result = ossClient.deleteObjects(new DeleteObjectsRequest(catalog).withKeys(fileNames));
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        StrategyFactory.register(FileStoreTypeEnum.ALIYUN, this);
    }
}